package softserve.vgolosh.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;

public class FileUtil {
	public static String TICKET_CREATION_COMMAND = "https://bits.bazaarvoice.com/jira/secure/CreateIssue!default.jspa";
	static {
		if (PropertiesHelper.isInitialised()) {
			try {
				TICKET_CREATION_COMMAND = PropertiesHelper
						.getProperty("TICKET_CREATION_COMMAND");
			} catch (PropertyNotFoundException e) {
				System.out.println(e);
				System.out.println("using default value "
						+ TICKET_CREATION_COMMAND);
			}
		}
	}

	public static List<String> getClientDirectories(String rootPath) {
		List<String> files = new ArrayList<String>();
		File dir = new File(rootPath);
		files = Arrays.asList(dir.list(new AndFileFilter(
				DirectoryFileFilter.INSTANCE, new NotFileFilter(
						new OrFileFilter(new PrefixFileFilter(".svn"),
								new PrefixFileFilter("default"))))));
		Collections.sort(files);
		return files;
	}

	static public List<String> getContents(String fileName) {
		List<String> result = new ArrayList<String>();
		try {
			File file = new File(fileName);
			BufferedReader input = new BufferedReader(new FileReader(file));
			try {
				String line = null;
				while ((line = input.readLine()) != null) {
					if (line.length() > 1) {
						result.add(line);
					}
				}
			} finally {
				input.close();
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		return result;
	}

	static public void writeListToFile(List<?> list, String filePath) {
		PrintStream output = null;
		try {
			try {
				File file = new File(filePath);
				System.out.println();
				output = new PrintStream(file);
				for (Object object : list) {
					output.println(object);
				}
			} finally {
				output.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	static public List<String> getClientNames(String rootPath) {
		List<String> result = new ArrayList<String>();
		Collection<File> files = new ArrayList<File>();
		List<String> directories = getClientDirectories(rootPath);
		BufferedReader input;
		for (String directory : directories) {
			files.add(new File(rootPath + directory
					+ "\\config\\clientConfiguration.xml"));
		}
		Pattern pattern = null;
		Matcher matcher = null;
		String regex1 = "<bean name=\"";
		String regex2 = "[0-9a-zA-Z_-]+";
		for (File file : files) {
			try {
				input = new BufferedReader(new FileReader(file));
				String line = null;
				while ((line = input.readLine()) != null) {
					pattern = Pattern.compile(regex1 + regex2);
					matcher = pattern.matcher(line);
					if (matcher.find()) {
						result.add(matcher.group().substring(regex1.length()));
						continue;
					}
				}
			} catch (Exception e) {
				System.out.println("problem with file");
			}
		}
		return result;
	}

	/*
	 * @param filepath - file to take commands from
	 * 
	 * @param clients - client names to specify
	 * 
	 * @param commands regex
	 */
	public static Map<String, String> getMergeCommands(String filePath,
			List<String> clients, String regex) {
		Map<String, String> result = new TreeMap<String, String>();
		List<String> data = getContents(filePath);
		Pattern pattern = null;
		Matcher matcher = null;
		for (String client : clients) {
			for (String value : data) {
				pattern = Pattern.compile(regex + client);
				matcher = pattern.matcher(value);
				if (matcher.find()) {
					result.put(client, matcher.group());
					continue;
				}
			}
		}
		return result;
	}

	/*
	 * @param filepath - file to take commands from
	 * 
	 * @param clients - client names to specify
	 * 
	 * @param commands regex
	 */
	public static Map<String, String> getCommitCommands(String filePath,
			List<String> clients) {
		Map<String, String> result = new TreeMap<String, String>();
		List<String> data = getContents(filePath);
		Pattern pattern = null;
		Matcher matcher = null;
		for (String client : clients) {
			for (String value : data) {
				pattern = Pattern.compile("bs scomt .{5} " + client + " c.");
				matcher = pattern.matcher(value);
				if (matcher.find()) {
					result.put(client, matcher.group());
					break;
				}
			}
		}
		return result;
	}

	public static List<String> getTicketCommands(String filePath) {
		List<String> result = new ArrayList<String>();
		List<String> data = getContents(filePath);
		Pattern pattern = null;
		Matcher matcher = null;
		for (String value : data) {
			pattern = Pattern.compile("https.*BVC-[\\d]{5,}");
			matcher = pattern.matcher(value);
			if (matcher.find()) {
				String ticket = matcher.group();
				if (!result.contains(ticket)) {
					result.add(ticket);
				}
				continue;
			} else {
				pattern = Pattern.compile("CLONE - (.*): migrate to \\d\\.\\d");
				matcher = pattern.matcher(value);
				if (matcher.find()) {
					result.add(TICKET_CREATION_COMMAND);
				}
			}
		}
		return result;
	}

	public static List<String> getClients(String filePath) {
		List<String> result = new ArrayList<String>();
		List<String> data = getContents(filePath);
		Pattern pattern = null;
		Matcher matcher = null;
		for (String value : data) {
			pattern = Pattern.compile("(^.+),(http|CLONE)");
			matcher = pattern.matcher(value);
			if (matcher.find()) {
				String client = matcher.group(1);

				if (!result.contains(client)) {
					result.add(client);
				}
			}
		}
		return result;
	}

	public static void copyToWorking(List<String> clients, String clean,
			String working) {
		List<String> existingClients = getClientDirectories(working);
		for (String client : clients) {
			try {
				System.out.println("copying " + client);
				if (!existingClients.contains(client)) {
					FileUtils.copyDirectory(new File(clean + client), new File(
							working + client));
				} else {
					System.out.println(" Already in working");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public static Map<String, String> getPromoteCommands(String file,
			List<String> clients) {
		Map<String, String> commitCommands = getCommitCommands(file, clients);
		Map<String, String> promoteCommands = new TreeMap<String, String>();
		String commitCommand = null;
		for (String client : clients) {
			commitCommand = commitCommands.get(client);
			commitCommand = commitCommand.replaceFirst("scomt", "spromt");
			promoteCommands.put(client, commitCommand);
		}
		return promoteCommands;
	}
}
